package com.smbpics

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Paint
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.caverock.androidsvg.SVG
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.ByteArrayInputStream
import android.os.Build

class ImageLoader(private val context: Context) {

    suspend fun loadImage(
        imageData: ByteArray,
        imageView: ImageView,
        fileName: String
    ) = withContext(Dispatchers.Main) {
        val extension = fileName.substringAfterLast('.', "").lowercase()

        try {
            when (extension) {
                "svg", "svgz" -> loadSvgImage(imageData, imageView)
                "pdf" -> loadPdfPreview(imageData, imageView)
                "webp" -> loadWebPImage(imageData, imageView)
                "avif" -> loadAvifImage(imageData, imageView)
                "tiff", "tif" -> loadTiffImage(imageData, imageView)
                "raw", "arw", "cr2", "cr3", "nef", "orf", "rw2", "pef", "srw", "dng" ->
                    loadRawImage(imageData, imageView, fileName)
                "heic", "heif" -> loadHeicImage(imageData, imageView)
                "hdr", "exr" -> loadHdrImage(imageData, imageView, fileName)
                else -> loadStandardImage(imageData, imageView)
            }
        } catch (e: Exception) {
            e.printStackTrace() // Log the error for debugging
            // Fallback to standard loading
            loadStandardImage(imageData, imageView)
        }
    }

    private suspend fun loadSvgImage(imageData: ByteArray, imageView: ImageView) {
        withContext(Dispatchers.IO) {
            try {
                val inputStream = ByteArrayInputStream(imageData)
                val svg = SVG.getFromInputStream(inputStream)
                val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
                val canvas = Canvas(bitmap)
                svg.setDocumentWidth(200f)
                svg.setDocumentHeight(200f)
                svg.renderToCanvas(canvas)

                withContext(Dispatchers.Main) {
                    imageView.setImageBitmap(bitmap)
                }
            } catch (e: Exception) {
                // Fallback to standard loading
                loadStandardImage(imageData, imageView)
            }
        }
    }

    private suspend fun loadPdfPreview(imageData: ByteArray, imageView: ImageView) {
        withContext(Dispatchers.IO) {
            try {
                // Create a simple PDF preview placeholder
                val bitmap = createPdfPreviewBitmap()
                withContext(Dispatchers.Main) {
                    imageView.setImageBitmap(bitmap)
                }
            } catch (e: Exception) {
                loadStandardImage(imageData, imageView)
            }
        }
    }

    private suspend fun loadRawImage(imageData: ByteArray, imageView: ImageView, fileName: String) {
        withContext(Dispatchers.IO) {
            try {
                // For RAW files, try to extract embedded JPEG preview
                val bitmap = extractRawPreview(imageData) ?: createRawPreviewBitmap(fileName)
                withContext(Dispatchers.Main) {
                    imageView.setImageBitmap(bitmap)
                }
            } catch (e: Exception) {
                loadStandardImage(imageData, imageView)
            }
        }
    }

    private suspend fun loadHeicImage(imageData: ByteArray, imageView: ImageView) {
        withContext(Dispatchers.IO) {
            try {
                // Try to decode HEIC using BitmapFactory (Android 9+)
                val options = BitmapFactory.Options()
                val bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.size, options)
                withContext(Dispatchers.Main) {
                    if (bitmap != null) {
                        imageView.setImageBitmap(bitmap)
                    } else {
                        loadStandardImage(imageData, imageView)
                    }
                }
            } catch (e: Exception) {
                loadStandardImage(imageData, imageView)
            }
        }
    }

    private suspend fun loadHdrImage(imageData: ByteArray, imageView: ImageView, fileName: String) {
        withContext(Dispatchers.IO) {
            try {
                // Create HDR preview placeholder
                val bitmap = createHdrPreviewBitmap(fileName)
                withContext(Dispatchers.Main) {
                    imageView.setImageBitmap(bitmap)
                }
            } catch (e: Exception) {
                loadStandardImage(imageData, imageView)
            }
        }
    }

    private suspend fun loadStandardImage(imageData: ByteArray, imageView: ImageView) {
        withContext(Dispatchers.Main) {
            Glide.with(context)
                .load(imageData)
                .apply(RequestOptions().fitCenter())
                .into(imageView)
        }
    }

    private fun createPdfPreviewBitmap(): Bitmap {
        val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        val paint = Paint().apply {
            color = 0xFFFF5722.toInt() // Orange color for PDF
            textAlign = Paint.Align.CENTER
            textSize = 24f
            isAntiAlias = true
        }
        canvas.drawColor(0xFFFFF3E0.toInt()) // Light orange background
        canvas.drawText("PDF", 100f, 100f, paint)
        canvas.drawText("Preview", 100f, 130f, paint)
        return bitmap
    }

    private fun createRawPreviewBitmap(fileName: String): Bitmap {
        val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        val paint = Paint().apply {
            color = 0xFF4CAF50.toInt() // Green color for RAW
            textAlign = Paint.Align.CENTER
            textSize = 20f
            isAntiAlias = true
        }
        canvas.drawColor(0xFFE8F5E8.toInt()) // Light green background
        canvas.drawText("RAW", 100f, 90f, paint)
        canvas.drawText(fileName.substringAfterLast('.').uppercase(), 100f, 120f, paint)
        return bitmap
    }

    private fun createHdrPreviewBitmap(fileName: String): Bitmap {
        val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        val paint = Paint().apply {
            color = 0xFF9C27B0.toInt() // Purple color for HDR
            textAlign = Paint.Align.CENTER
            textSize = 20f
            isAntiAlias = true
        }
        canvas.drawColor(0xFFF3E5F5.toInt()) // Light purple background
        canvas.drawText("HDR", 100f, 90f, paint)
        canvas.drawText(fileName.substringAfterLast('.').uppercase(), 100f, 120f, paint)
        return bitmap
    }

    private fun extractRawPreview(imageData: ByteArray): Bitmap? {
        return try {
            // Try to decode as standard image first (some RAW files contain JPEG previews)
            BitmapFactory.decodeByteArray(imageData, 0, imageData.size)
        } catch (e: Exception) {
            null
        }
    }

    private suspend fun loadWebPImage(imageData: ByteArray, imageView: ImageView) {
        try {
            // Let Glide handle WebP - it has excellent WebP support including animated WebP
            withContext(Dispatchers.Main) {
                Glide.with(context)
                    .load(imageData)
                    .apply(RequestOptions()
                        .fitCenter()
                        .placeholder(android.R.drawable.ic_menu_gallery)
                        .error(android.R.drawable.ic_dialog_alert))
                    .into(imageView)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            // Try BitmapFactory as fallback
            withContext(Dispatchers.IO) {
                try {
                    val bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.size)
                    withContext(Dispatchers.Main) {
                        if (bitmap != null) {
                            imageView.setImageBitmap(bitmap)
                        } else {
                            loadStandardImage(imageData, imageView)
                        }
                    }
                } catch (ex: Exception) {
                    ex.printStackTrace()
                    loadStandardImage(imageData, imageView)
                }
            }
        }
    }

    private suspend fun loadAvifImage(imageData: ByteArray, imageView: ImageView) {
        withContext(Dispatchers.IO) {
            var loadSuccess = false

            // Method 1: Try BitmapFactory (Android 12+ has native AVIF support)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // API 31+
                try {
                    val options = BitmapFactory.Options().apply {
                        inJustDecodeBounds = false
                        inPreferredConfig = Bitmap.Config.ARGB_8888
                    }
                    val bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.size, options)

                    if (bitmap != null) {
                        withContext(Dispatchers.Main) {
                            imageView.setImageBitmap(bitmap)
                            loadSuccess = true
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }

            // Method 2: Try Glide as fallback for older Android versions or BitmapFactory failure
            if (!loadSuccess) {
                withContext(Dispatchers.Main) {
                    try {
                        Glide.with(context)
                            .load(imageData)
                            .apply(RequestOptions()
                                .fitCenter()
                                .placeholder(android.R.drawable.ic_menu_gallery)
                                .error(android.R.drawable.ic_dialog_alert))
                            .into(object : com.bumptech.glide.request.target.CustomTarget<android.graphics.drawable.Drawable>() {
                                override fun onResourceReady(
                                    resource: android.graphics.drawable.Drawable,
                                    transition: com.bumptech.glide.request.transition.Transition<in android.graphics.drawable.Drawable>?
                                ) {
                                    imageView.setImageDrawable(resource)
                                }

                                override fun onLoadCleared(placeholder: android.graphics.drawable.Drawable?) {
                                    // Do nothing
                                }

                                override fun onLoadFailed(errorDrawable: android.graphics.drawable.Drawable?) {
                                    // Show informative AVIF placeholder
                                    val placeholder = createAvifPreviewBitmap(isSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
                                    imageView.setImageBitmap(placeholder)
                                }
                            })
                    } catch (e: Exception) {
                        e.printStackTrace()
                        // Create informative placeholder
                        val placeholder = createAvifPreviewBitmap(isSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
                        imageView.setImageBitmap(placeholder)
                    }
                }
            }
        }
    }

    private fun createAvifPreviewBitmap(isSupported: Boolean = false): Bitmap {
        val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        val paint = Paint().apply {
            textAlign = Paint.Align.CENTER
            isAntiAlias = true
        }

        // Background and main color based on support status
        if (isSupported) {
            canvas.drawColor(0xFFE8F5E8.toInt()) // Light green background
            paint.color = 0xFF4CAF50.toInt() // Green for supported
        } else {
            canvas.drawColor(0xFFFFE0B2.toInt()) // Light orange background
            paint.color = 0xFFFF9800.toInt() // Orange for limited support
        }

        // Main AVIF text
        paint.textSize = 28f
        canvas.drawText("AVIF", 100f, 70f, paint)

        // Format description
        paint.textSize = 14f
        canvas.drawText("Next-Gen Image", 100f, 100f, paint)

        // Status information
        paint.textSize = 12f
        if (isSupported) {
            paint.color = 0xFF2E7D32.toInt() // Dark green
            canvas.drawText("Native Support", 100f, 125f, paint)
            canvas.drawText("(Android 12+)", 100f, 145f, paint)
        } else {
            paint.color = 0xFFE65100.toInt() // Dark orange
            canvas.drawText("Limited Support", 100f, 125f, paint)
            canvas.drawText("(Android < 12)", 100f, 145f, paint)
        }

        return bitmap
    }

    private suspend fun loadTiffImage(imageData: ByteArray, imageView: ImageView) {
        withContext(Dispatchers.IO) {
            var loadSuccess = false

            // Method 1: Try BitmapFactory first (limited TIFF support in Android)
            try {
                val options = BitmapFactory.Options().apply {
                    inJustDecodeBounds = false
                    inPreferredConfig = Bitmap.Config.ARGB_8888
                    inSampleSize = 1 // Don't downsample initially
                }
                val bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.size, options)

                if (bitmap != null) {
                    withContext(Dispatchers.Main) {
                        imageView.setImageBitmap(bitmap)
                        loadSuccess = true
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }

            // Method 2: Try Glide as fallback
            if (!loadSuccess) {
                withContext(Dispatchers.Main) {
                    try {
                        Glide.with(context)
                            .load(imageData)
                            .apply(RequestOptions()
                                .fitCenter()
                                .placeholder(android.R.drawable.ic_menu_gallery)
                                .error(android.R.drawable.ic_dialog_alert))
                            .into(object : com.bumptech.glide.request.target.CustomTarget<android.graphics.drawable.Drawable>() {
                                override fun onResourceReady(
                                    resource: android.graphics.drawable.Drawable,
                                    transition: com.bumptech.glide.request.transition.Transition<in android.graphics.drawable.Drawable>?
                                ) {
                                    imageView.setImageDrawable(resource)
                                }

                                override fun onLoadCleared(placeholder: android.graphics.drawable.Drawable?) {
                                    // Do nothing
                                }

                                override fun onLoadFailed(errorDrawable: android.graphics.drawable.Drawable?) {
                                    // Show TIFF placeholder
                                    val placeholder = createTiffPreviewBitmap()
                                    imageView.setImageBitmap(placeholder)
                                }
                            })
                    } catch (e: Exception) {
                        e.printStackTrace()
                        // Create TIFF placeholder
                        val placeholder = createTiffPreviewBitmap()
                        imageView.setImageBitmap(placeholder)
                    }
                }
            }
        }
    }

    private fun createTiffPreviewBitmap(): Bitmap {
        val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        val paint = Paint().apply {
            textAlign = Paint.Align.CENTER
            isAntiAlias = true
        }

        // Background and colors for TIFF
        canvas.drawColor(0xFFF3E5F5.toInt()) // Light purple background
        paint.color = 0xFF9C27B0.toInt() // Purple for TIFF

        // Main TIFF text
        paint.textSize = 28f
        canvas.drawText("TIFF", 100f, 70f, paint)

        // Format description
        paint.textSize = 14f
        canvas.drawText("Professional", 100f, 100f, paint)
        canvas.drawText("Image Format", 100f, 120f, paint)

        // Status information
        paint.textSize = 12f
        paint.color = 0xFF7B1FA2.toInt() // Darker purple
        canvas.drawText("Limited Android", 100f, 145f, paint)
        canvas.drawText("Support", 100f, 165f, paint)

        return bitmap
    }
}